#pragma once
#include"Socket.hpp"
#include<memory>
#include<sys/wait.h>
#include<functional>
using namespace SocketMoudle;
using namespace LogMoudle;
using ioservice_t =std::function<void(std::shared_ptr<Socket>&socket,NetAddr&client)>;
class TcpServer{
public:
    TcpServer(uint16_t port):
        _port(port),
        _listen_socket(std::make_unique<TcpSocket>()){
            _listen_socket->BuildListenSocket(_port);
        }
        void Start(ioservice_t ioservice){
            _isrunning = true;
            LOG(LogLevel::INFO)<<"server is running...";
            while(_isrunning){
                NetAddr client;
                auto sock=_listen_socket->Accept(&client);
                if(sock==nullptr){
                    continue;
                }
                LOG(LogLevel::INFO)<<"accept is sucessful";
                //std::cout << "accept ok, pid=" << getpid() << " fd="<<sock->GetSockFd()<<std::endl;
                //获得sock和client
                pid_t id =fork();
                if(id<0){
                    LOG(LogLevel::ERROR)<<"fork error";
                }
                else if(id==0){
                    //子进程
                    //处理请求
                    _listen_socket->Close();
                    if(fork()>0){
                        //子进程
                        //直接结束子进程，让孙子进程变成孤儿进程让系统处理
                        exit(0);
                    }
                    //孙子进程执行任务
                    ioservice(sock, client);

                }
                else{
                    sock->Close();
                    pid_t rid=waitpid(id,nullptr,0);
                }
            }
            LOG(LogLevel::INFO)<<"server is stoped ...";
            _isrunning = false;
        }
        void Stop(){
            _isrunning = false;
        }
private:
    uint16_t _port;
    std::unique_ptr<TcpSocket> _listen_socket;
    bool _isrunning;
};